package org.dizena.common.trace.feign;

import feign.codec.Decoder;
import feign.optionals.OptionalDecoder;
import jakarta.annotation.Resource;
import org.dizena.common.trace.feign.handler.FeignErrorDecoder;
import org.dizena.common.trace.feign.handler.FeignTraceDecoder;
import org.dizena.common.trace.feign.handler.FeignTraceInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(FeignTraceAutoProperties.class)
@ConditionalOnProperty(
        prefix = "common.trace.feign",
        value = {"enabled"},
        havingValue = "true"
)
public class FeignTraceAutoConfig implements CommandLineRunner {
    private Logger logger = LoggerFactory.getLogger(FeignTraceAutoConfig.class);

    @Resource
    private FeignTraceAutoProperties feignTraceProperties;

    private ApplicationEventPublisher publisher;

    @Autowired
    public void setPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    private ObjectFactory<HttpMessageConverters> messageConverters;

    @Autowired
    public void setMessageConverters(ObjectFactory<HttpMessageConverters> messageConverters) {
        this.messageConverters = messageConverters;
    }

    @Bean
    public FeignTraceInterceptor feignTraceRequestInterceptor() {
        return new FeignTraceInterceptor(feignTraceProperties, publisher);
    }

    @Bean
    public Decoder feignDecoder() {
        return new OptionalDecoder(new ResponseEntityDecoder(new FeignTraceDecoder(publisher,new SpringDecoder(messageConverters))));
    }

    @Bean
    public FeignErrorDecoder feignErrorDecoder() {
        return new FeignErrorDecoder(publisher);
    }

    @Override
    public void run(String... args) {
        logger.info("【自动化配置】---Feign Trace 配置初始化");
    }
}
